import 'dart:async';

import 'package:rxdart/rxdart.dart';

import '../../common/test_page.dart';

class RepeatTestPage extends TestPage {
  RepeatTestPage(super.title) {
    test('Rx.repeat', () async {
      const retries = 3;

      expect(Rx.repeat(_getRepeatStream('A'), retries));
    });

    test('RepeatStream', () async {
      const retries = 3;

      expect(RepeatStream(_getRepeatStream('A'), retries));
    });

    test('RepeatStream.onDone', () async {
      const retries = 0;

      expect(RepeatStream(_getRepeatStream('A'), retries));
    });

    test('RepeatStream.infinite.repeats', () async {
      expect(RepeatStream(_getRepeatStream('A')));
    });

    test('RepeatStream.single.subscription', () async {
      const retries = 3;

      final stream = RepeatStream(_getRepeatStream('A'), retries);

      try {
        stream.listen(null);
        stream.listen(null);
      } catch (e) {
        expect(e);
      }
    });

    test('RepeatStream.asBroadcastStream', () async {
      const retries = 3;

      final stream =
      RepeatStream(_getRepeatStream('A'), retries).asBroadcastStream();

      // listen twice on same stream
      stream.listen(null);
      stream.listen(null);
      // code should reach here
      expect(stream.isBroadcast);
    });

    test('RepeatStream.error.shouldThrow', () async {
      final streamWithError = RepeatStream(_getErroneusRepeatStream('A'), 2);

      expect(streamWithError);
    });

    test('RepeatStream.pause.resume', () async {
      late StreamSubscription<String> subscription;
      const retries = 3;

      subscription = RepeatStream(_getRepeatStream('A'), retries)
          .listen(((result) {
        expect(result);

        subscription.cancel();
      }));

      subscription.pause();
      subscription.resume();
    });
  }

  Stream<String> Function(int) _getRepeatStream(String symbol) =>
          (int repeatIndex) async* {
        yield await Future.delayed(
            const Duration(milliseconds: 20), () => '$symbol$repeatIndex');
      };

  Stream<String> Function(int) _getErroneusRepeatStream(String symbol) =>
          (int repeatIndex) {
        return Stream.value('A0')
            .concatWith([Stream<String>.error(Error())]);
      };

}